package com.hmdp.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.hmdp.dto.UserDTO;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class RefreshTokenInterceptor implements HandlerInterceptor {
    private StringRedisTemplate redisTemplate;

    public RefreshTokenInterceptor(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /*//1.获取session
        HttpSession session = request.getSession();
        //2.获取session中的用户
        Object user = session.getAttribute("user");
        //3.判断用户是否存在，如果存在，则放行，
        if(user==null){
            // 4.不存在，则拦截
            response.setStatus(401);
            return false;
        }
        //5.存在，则保存用户信息到ThreadLocal
        UserHolder.saveUser((UserDTO) user);
        //6.放行*/
        //1.获取token
        String token = request.getHeader("authorization");
        if (StrUtil.isAllBlank(token)) {
            return true;
        }
        //这个拦截器的作用实质上就是为了识别用户的身份，只有知道了用户的身份才能进行相关用户后续的操作
        //当然对于一些不用登录的操作，比如查看文章列表、查看文章详情等，那么就不需要这个拦截器了
        //用户在Redis中存放的key是 login:token:token，所以先拼接上login:token:
        //然后如果用户发出的请求中有token，则直接根据token获取Redis中的用户即可
        //利用这个方法可以让服务器区分请求是那个用户发出的、
        //每次用户发起请求都会更新token的有效期
        //如果用户长时间没有进行服务器访问操作那么这个token也就会失效
        //用户需要重新登录获取新的token才能进行后续的操作
        //2.基于token获取Redis中的用户
        Map<Object, Object> entries = redisTemplate.opsForHash().entries( RedisConstants.LOGIN_USER_KEY+ token);
        //判断用户是否存在
        if(entries.isEmpty()){
            // 不存在，则拦截
            return true;
        }
        //3.将查询到的哈希数据转换成user对象
        UserDTO userDTO = BeanUtil.fillBeanWithMap(entries, new UserDTO(), false);
        //4.保存用户到ThreadLocal
        UserHolder.saveUser(userDTO);
        //5.刷新token的有效期
        redisTemplate.expire(RedisConstants.LOGIN_USER_KEY+token,RedisConstants.LOGIN_USER_TTL, TimeUnit.SECONDS);
        //放行
        return true;
    }
}
